use std::{collections::HashMap, fs, path::Path, sync::Arc};

use arc_swap::ArcSwapOption;
use definition::Config;
use import_conf::{ImportConfig, ImportConfigs};
use once_cell::sync::Lazy;
use shq_common::prelude::get_work_path;
pub mod definition;
pub mod import_conf;

static EXCEL_DATA_CONFS: Lazy<ArcSwapOption<HashMap<String, &'static Config>>> =
    Lazy::new(|| ArcSwapOption::const_empty());
static EXCEL_IMPORT_CONFS: Lazy<ArcSwapOption<&'static ImportConfigs>> = Lazy::new(||ArcSwapOption::const_empty());

pub (crate) async fn init_excel_rept_config() -> anyhow::Result<()> {
    let conf_path = format!("{}/excel_rept_confs", get_work_path());
    let mut conf_map: HashMap<String, &'static Config> = HashMap::new();
    for entry in fs::read_dir(conf_path)? {
        let entry = entry?;
        let path = entry.path();
        if path.is_dir() {
            continue;
        } else {
            let file_name = path.file_name().unwrap().to_str().unwrap();
            if !file_name.ends_with(".yaml") {
                continue;
            }
            let conf_str = fs::read_to_string(&path)?;
            let conf: Config = serde_yaml::from_str(&conf_str)
                .or_else(|err| Err(anyhow::anyhow!("yaml文件{}解析失败:{err}",file_name)))?;
            conf.parse()
                .or_else(|err| Err(anyhow::anyhow!("yaml文件{}解析失败:{err}",file_name)))?;
            let conf_ref = Box::leak(Box::new(conf));
            let file_name = &file_name[0..file_name.len() - 5];
            conf_map.insert(file_name.to_string(), conf_ref);
        }
    }
    EXCEL_DATA_CONFS.store(Some(Arc::new(conf_map)));
    Ok(())
}
pub async fn reload_excel_rept_config(path: &Path) -> anyhow::Result<()> {
    let file_name = path.file_name().unwrap().to_str().unwrap();
    if !file_name.ends_with(".yaml") {
        return Ok(());
    }
    let rept_name = &file_name[0..file_name.len() - 5];
    let conf_path = format!("{}/excel_rept_confs/{}.yaml", get_work_path(), rept_name);
    let conf_str = fs::read_to_string(&conf_path)?;
    let conf: Config = serde_yaml::from_str(&conf_str)
        .or_else(|err| Err(anyhow::anyhow!("yaml文件{}解析失败:{err}",rept_name)))?;
    let conf_ref = Box::leak(Box::new(conf));
    let conf_map = EXCEL_DATA_CONFS.load().clone().unwrap();
    let mut conf_map2: HashMap<String, &'static Config> = HashMap::new();
    for (k, v) in conf_map.iter() {
        if k == rept_name {
            conf_map2.insert(k.clone(), conf_ref);
        } else {
            conf_map2.insert(k.clone(), *v);
        }
    }
    EXCEL_DATA_CONFS.store(Some(Arc::new(conf_map2)));
    Ok(())
}
pub async fn init_excel_import_config() -> anyhow::Result<()> {
    let conf_path = format!("{}/config_files/excel_import.yaml", get_work_path());
    let conf_str = fs::read_to_string(&conf_path)?;
    let conf_vec: Vec<ImportConfig> = serde_yaml::from_str(&conf_str)
        .or_else(|err| Err(anyhow::anyhow!("yaml文件{}解析失败:{err}",conf_path)))?;
    let confs=ImportConfigs::new(conf_vec);
    let conf_ref = Box::leak(Box::new(confs));
    EXCEL_IMPORT_CONFS.store(Some(Arc::new(conf_ref)));
    Ok(())
}

pub fn get_excel_rept_config(name: &str) -> Option<&'static Config> {
    EXCEL_DATA_CONFS.load().as_ref()?.get(name).copied()
}
pub fn get_excel_import_config() -> &'static ImportConfigs {
    EXCEL_IMPORT_CONFS.load().clone().unwrap().as_ref()
}